package com.zds.passwordbox.data.dao;

import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.zds.passwordbox.common.Constant;
import com.zds.passwordbox.common.util.CryptoUtil;
import com.zds.passwordbox.data.dao.domain.PrivateKey;


public class PrivateKeyDao {
    private final SQLiteDatabase db;

    private static final String USER_KEY = "user_key";

    private volatile static PrivateKeyDao instance;

    private String initSecretKey;

    public static synchronized PrivateKeyDao getInstance(SQLiteDatabase db) {
        if (instance == null) {
            instance = new PrivateKeyDao(db);
        }
        return instance;
    }

    public PrivateKeyDao(SQLiteDatabase db) {
        this.db = db;
    }

    private synchronized void initAppSecretKey() {
        PrivateKey initSecret = query("initSecret");
        if (initSecret.getSecret() != null) {
            this.initSecretKey = initSecret.getSecret();
            return;
        }
        String secretKey = CryptoUtil.generateInitSecretKey();
        insert(new PrivateKey().setKey("initSecret").setSecret(secretKey));
        this.initSecretKey = secretKey;
    }

    public boolean isUserKeyExist() {
        PrivateKey userKey = query(USER_KEY);
        return userKey.getSecret() != null;
    }

    public String getUserKey() {
        PrivateKey userKey = query(USER_KEY);
        if (userKey.getSecret().isEmpty()) {
            throw new RuntimeException("未配置用户个人密钥！");
        }
        if (this.initSecretKey == null) {
            initAppSecretKey();
        }
        try {
            return CryptoUtil.decrypt(this.initSecretKey, userKey.getSecret());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public void saveUserKey(String userKey) {
        if (this.initSecretKey == null) {
            initAppSecretKey();
        }
        try {
            String encryptTxt = CryptoUtil.encrypt(this.initSecretKey,
                    userKey.getBytes(CryptoUtil.CHARSET_UTF8));
            insert(new PrivateKey().setKey(USER_KEY).setSecret(encryptTxt));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    private void insert(PrivateKey privateKey) {
        privateKey.setId(null);
        ContentValues values = getContentValues(privateKey);
        //参数依次是：表名，插入null值的数据列的列名，数据
        db.insert(Constant.PRIVATE_KEY_TABLE, null, values);
    }

    private void update(PrivateKey privateKey) {
        ContentValues values = getContentValues(privateKey);
        //参数依次是表名，修改后的值，where条件，以及约束，如果不指定三四两个参数，会更改所有行
        db.update(Constant.PRIVATE_KEY_TABLE, values,
                "key = ?", new String[]{privateKey.getKey()});
    }

    private PrivateKey query(String key) {
        PrivateKey privateKey = new PrivateKey();
        //创建游标对象
        Cursor cursor = db.query(Constant.PRIVATE_KEY_TABLE,
                new String[]{"id", "key", "secret"},
                "key = ?", new String[]{key},
                null, null, null);
        //利用游标遍历所有数据对象
        if (cursor.moveToFirst()) {
            String secret = cursor.getString(cursor.getColumnIndexOrThrow("secret"));
            // 关闭游标，释放资源
            cursor.close();
            privateKey.setSecret(secret);
        }
        return privateKey;
    }

    private ContentValues getContentValues(PrivateKey privateKey) {
        ContentValues values = new ContentValues();
        values.put("id", privateKey.getId());
        values.put("key", privateKey.getKey());
        values.put("secret", privateKey.getSecret());
        return values;
    }

}
